#include "mapas.h"
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <set>
#include "math.h"
#include <string>
#include <stdio.h>
//#include "conio2.h"
//#include "ncurses.h"


using namespace std;


Mapa :: Mapa(string nombre) {

    char c = 'A';
    string nombre_ciudad;
    string nombre_foco;
    unsigned coord_x, coord_y;
    set<Ciudad>::const_iterator iter; //creo un iterador para la lista
    fstream fich;
    fich.open(nombre.c_str());
    fich >> n;
    fich >> m;
    fich >> num_ciudades;
    fich >> num_focos;
    for (int i= 0; i < num_ciudades; i++){
   	for (int j=0; j < 3; j++){
	    fich >> nombre_ciudad;
	    fich >> coord_x;
	    fich >> coord_y;
	}
        if (Margenes(coord_x,coord_y,false)){	
            Ciudad *ciudad_actual;
            ciudad_actual = new Ciudad (i+1, nombre_ciudad, coord_x, coord_y); //Creo un nuevo objeto ciudad       
            ciudades.insert (*ciudad_actual); //se lo añado a el conjunto
            delete ciudad_actual;
        }
    }
    for (int i= 0; i < num_focos; i++){
        for (int j=0; j < 3; j++){
            fich >> nombre_foco;
	    fich >> coord_x;
	    fich >> coord_y;
	}
        if (Margenes(coord_x,coord_y,true)){	
            Foco *foco_actual;
            foco_actual = new Foco (c, nombre_foco, coord_x, coord_y); //Creo un nuevo objeto ciudad       
            focos.insert (*foco_actual); //se lo añado a el conjunto
            delete foco_actual;
	}
	for (iter = ciudades.begin(); iter != ciudades.end(); iter++){
                //Le hago el valor absoluto para dejarlo positivo ya que es la misma distancia 6-2=4 que 2-6=-4
	    distancias[i][iter->Obtener_id() - 1] = abs(iter-> Obtener_x() - x) + abs(iter-> Obtener_y() - y);
        }
        c++;

    }
}

//Sobrecarga del constructor de la clase mapa para generar aleatoriamente un mapa nuevo
Mapa :: Mapa() {
   char c = 'A';
   char d = 'A';
   string nombre_aleat;
   unsigned coord_x, coord_y;
   set<Ciudad>::const_iterator iter; //creo un iterador para la lista
   srand(time(NULL)); // Inicializa el generador de nos. aleatorios con semilla arbitraria
   
   n = 25+rand()%(61-25); //genero un numero entre el 25 y el 60 para las columnas
   m = 10+rand()%(20-10);//alto o filas
   
   do{
      num_ciudades = 5+rand()%(21-5);
      num_focos = 3+rand()%(11-3);
   }while((num_ciudades+num_focos) > (n*m));//repetir mientras el numero de ciudades mas el de focos sea mayor al espacio en el mapa

   for (int i= 0; i < num_ciudades; i++){
       nombre_aleat = d;
       coord_x = 1+rand()%((n+1)-1);
       coord_y = 1+rand()%((m+1)-1);
       if (Margenes (coord_x, coord_y,false)) {
           Ciudad *ciudad_actual;
           ciudad_actual = new Ciudad (i+1, nombre_aleat, coord_x, coord_y); //Creo un nuevo objeto ciudad       
           ciudades.insert (*ciudad_actual); //se lo añado a el conjunto
           delete ciudad_actual;
           d++;
       }
   }

   for (int i= 0; i < num_focos; i++){
       nombre_aleat = d;
       coord_x = 1+rand()%((n+1)-1);
       coord_y = 1+rand()%((m+1)-1); 
       if (Margenes (coord_x, coord_y, true)) {
           Foco *foco_actual;
           foco_actual = new Foco (c, nombre_aleat, coord_x, coord_y); //Creo un nuevo objeto foco      
           focos.insert (*foco_actual); //se lo añado a el conjunto
           delete foco_actual;
       }   
       for (iter = ciudades.begin(); iter != ciudades.end(); iter++){
       //Le hago el valor absoluto para dejarlo positivo ya que es la misma distancia 6-2=4 que 2-6=-4
           distancias[i][iter->Obtener_id() - 1] = abs(iter-> Obtener_x() - x) + abs(iter-> Obtener_y() - y);
       }
       c++;
       d++;
   }


}

bool Mapa :: Margenes (unsigned cord_x, unsigned cord_y, bool edificio) {

    set<Ciudad>::const_iterator iter;
    set<Foco>::const_iterator iter2;
    bool margen = false;

    if ((cord_x >= x) || (cord_y >= y)) { //Si las coordenadas son mayores que la longitud del mapa no entra
        return false;
    }
    if (edificio == false) { //En los casos contrarios si es una ciudad,
        for (iter = ciudades.begin(); iter != ciudades.end(); iter++) 
            if ((iter->Obtener_x() == cord_x) && (iter->Obtener_y() == cord_y)) //si ya tenemos estas coordenadas
	        return false;                                               //no metemos la ciudad dentro del conjunto
        return true;	    
    }
    else if (edificio == true) { // En caso de ser un foco
        for (iter2 = focos.begin(); iter2 != focos.end(); iter2++) 
            if ((iter2->Obtener_x() ==cord_x) && (iter2->Obtener_y() ==cord_y))
                return false;
        return true;
    }
}
void Mapa :: Colocar_instalaciones(unsigned num) {




}
//80 columnas, 24 filas
void Mapa :: Mostrar_mapa() {

    set<Ciudad>::const_iterator iter; //creo un iterador para el conjunto ciudad
    set<Foco>::const_iterator iter2; //creo un iterador para el conjunto ciudad
    //gotoxy(20,5);
    for (int i =0;i <= m; i++) { //filas
        for (int j = 0; j <= n; j++) { //columnas
            if ((i == 0) || (i == m))
                cout << "\033[01;37m-";
            if ((j == 0) || (j == n))
                cout << "\033[01;37m|";
            else
                cout << " ";
            for (iter = ciudades.begin(); iter != ciudades.end(); iter++) {
                if ((iter->Obtener_x() == j) && (iter->Obtener_y() == i))
                    cout << "\033[22;32m*"; //ciudad colocada :)// podemos poner tamb el identificador
            }
            for (iter2 = focos.begin(); iter2 != focos.end(); iter2++) {
                if ((iter2->Obtener_x() ==j) && (iter2->Obtener_y() ==i))
                    cout << "\033[01;34m#"; //posible foco colocado :)
            }
        }
    }
    //getch();
    //gotoxy(60,20);
    cout << "\033[22;32m* Ciudad"<< endl;
    cout << "\033[01;34m# Posible Foco" << endl;
    cout << "\033[01;33m# Foco" << endl;
    //getch();
}
